package unitTests;

import java.util.Calendar;

import increment1.*;

import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

/**
 * PersonUnitTests class contains the units tests of the methods in the Person class 
 * 
 * @author Amer Alhalabi/Rolf Schmidt
 *
 */
public class PersonUnitTests {

	final String H_LINE = "---------------------------------------";
	final String DATE_FORMAT = "yyyy-MM-dd";
	final int LONG_STRING = 100;
	final int VERY_LONG_STRING = 2000;
	final String WILD_STRING = "*@&(|}{+?~+\\/";
	StringBuffer sbLong;
	StringBuffer sbVeryLong;
	
	@Before
	public void setUp() {
		sbLong = new StringBuffer(LONG_STRING);
		for (int i = 0; i < LONG_STRING; i++) {
			sbLong.append("a");
		}
		
		sbVeryLong = new StringBuffer(VERY_LONG_STRING);
		for (int i = 0; i < VERY_LONG_STRING; i++) {
			sbVeryLong.append("a");
		}
    }
	
	public PersonUnitTests() {
    }
	
	@Test
	public void testPersonConstructor() {
        Person person = new Person();
        
        assertEquals("nobody", person.getName());
        assertEquals(0, person.getHours());
        assertTrue(person.getTasks().isEmpty());
    }
	
	@Test
	public void testPersonToStringNew() {
		
		// create a new person object
		Person person = new Person();
		
		// create a string
		StringBuffer sb = new StringBuffer(H_LINE);
		sb.append("\nName: " + "nobody");
		sb.append("\nHours: " + 0); 
		sb.append("\nTasks: " + ""); 
		sb.append("\n" + H_LINE + "\n");
		
		// test
		assertEquals(sb.toString(), person.toString());
	}

	@Test
	public void testPersonToStringModified() {
		// create a new person object
		Person person = new Person();
		// modify the person object
		person.setName("Jack Frankie");

		// create a string
		StringBuffer sb = new StringBuffer(H_LINE);
		sb.append("\nName: " + "Jack Frankie");
		sb.append("\nHours: " + 0); 
		sb.append("\nTasks: " + ""); 
		sb.append("\n" + H_LINE + "\n");
		
		// test
		assertEquals(sb.toString(), person.toString());
		
		// clear string buffer
		sb.delete(0, sb.length());
		
		// modify person again by adding a task
		Task task = new Task();
		Calendar testDeadline = Calendar.getInstance();
		task.setDeadline(testDeadline);
		task.setId("Test task");
		task.setTitle("Test title");
		task.setDescription("Test description");
		task.setDuration(25);
		task.setDeliverable("Test deliverable");
		task.setPerson("Jack Frankie");
		
		person.addTask(task);
		
		// create the equivalent
		sb.append(H_LINE);
		sb.append("\nName: " + "Jack Frankie");
		sb.append("\nHours: " + 25);
		sb.append("\nTasks: Test task");
		sb.append("\n" + H_LINE + "\n");
		
		// test
		assertEquals(sb.toString(), person.toString());
	}
	
	@Test
	public void testPersonEquals1() {
		Person person = new Person();
		
		assertTrue(person.equals(person));
	}
	
	@Test
	public void testPersonEquals2() {
		
		Person person1 = new Person();
		Person person2 = new Person();
		
		person1.setName("Jakie hyman");
		person2.setName("Jakie hyman");
		
		assertNotSame(person1, person2);
		assertTrue(person1.equals(person2));
		assertTrue(person2.equals(person1));
	}
	
	@Test
	public void testPersonEquals3() {
		Person person1 = new Person();
		Person person2 = new Person();
		
		/// space difference
		person1.setName("Jakie hyman ");
		person2.setName("Jakie hyman");
		
		assertNotSame(person1, person2);
		assertFalse(person1.equals(person2));
		assertFalse(person2.equals(person1));
	}
	
	@Test
	public void testPersonEquals4() {
		
		Person person = new Person();
		String test = "test different object";
		assertFalse(person.equals(test));
	}
	
	@Test
	public void testPersonEquals5() {
		Person person = new Person();
		assertFalse(person.equals(null));
	}
	
	@Test
	public void testPersonEquals6() {
		Person person1 = new Person();
		Person person2 = new Person();
		Person person3 = new Person();
		
		// prep1
		person1.setName("Mark Smith");
		person2.setName(null);
		
		// test1
		assertFalse(person1.equals(person2));
		
		// perp2
		person2.setName("Mark Smith");
		
		Task task = new Task();
		Calendar testDeadline = Calendar.getInstance();
		task.setDeadline(testDeadline);
		task.setId("Test task");
		task.setTitle("Test title");
		task.setDescription("Test description");
		task.setDuration(25);
		task.setDeliverable("Test deliverable");
		task.setPerson("Mark Smith");
		
		person1.addTask(task);
		person2.addTask(null);
		
		// test2
		assertFalse(person1.equals(person2));
		
		//prep3
		person3.setName("Mark Smith");
		person3.addTask(task);
		
		// test3
		assertTrue(person1.equals(person3));
	}
	
	@Test
	public void testPersonSetName1() {
		Person person = new Person();
		person.setName("");
		assertEquals("nobody", person.getName());
	}
	
	@Test
	public void testPersonSetName2() {
		
		Person person = new Person();
		person.setName(sbLong.toString());
		assertEquals(sbLong.toString(), person.getName());
	}
	
	@Test
	public void testPersonSetName3() {
		
		Person person = new Person();
		person.setName(null);
		assertEquals("nobody", person.getName());
	}
	
	@Test
	public void testPersonSetName4() {
		Person person = new Person();
		person.setName(WILD_STRING);
		assertEquals(WILD_STRING, person.getName());
	}
	
	@Test
	public void testPersonAddTask1() {
		// positive duration
	
		String name = "Mark Smith";
		Task task = new Task();
		Calendar testDeadline = Calendar.getInstance();
		task.setDeadline(testDeadline);
		task.setId("Test task");
		task.setTitle("Test title");
		task.setDescription("Test description");
		task.setDuration(25);
		task.setDeliverable("Test deliverable");
		task.setPerson(name);
		
		Person person = new Person();
		person.setName(name);
		person.addTask(task);
		
		assertEquals(person.getHours(), 25);
		
	}
	
	@Test
	public void testPersonAddTask2() {
		// zero duration
	
		String name = "Mark Smith";
		Task task = new Task();
		Calendar testDeadline = Calendar.getInstance();
		task.setDeadline(testDeadline);
		task.setId("Test task");
		task.setTitle("Test title");
		task.setDescription("Test description");
		task.setDuration(0);
		task.setDeliverable("Test deliverable");
		task.setPerson(name);
		
		Person person = new Person();
		person.setName(name);
		person.addTask(task);
		
		assertEquals(person.getHours(), 1);
		
	}
	
	@Test
	public void testPersonAddTask3() {
		// positive duration
	
		String name = "Mark Smith";
		Task task = new Task();
		Calendar testDeadline = Calendar.getInstance();
		task.setDeadline(testDeadline);
		task.setId("Test task");
		task.setTitle("Test title");
		task.setDescription("Test description");
		task.setDuration(-5);
		task.setDeliverable("Test deliverable");
		task.setPerson(name);
		
		Person person = new Person();
		person.setName(name);
		person.addTask(task);
		
		assertEquals(person.getHours(), 1);
		
	}
	
	@Test
	public void testPersonAddTask4() {
		// null task
		
		String name = "Mark Smith";
		Person person = new Person();
		person.setName(name);
		person.addTask(null);
		
		assertEquals(person.getHours(), 0);
	}
	
	@Test
	public void testPersonAddTask5() {
		// add the same task twice duration
	
		String name = "Mark Smith";
		Task task = new Task();
		Calendar testDeadline = Calendar.getInstance();
		task.setDeadline(testDeadline);
		task.setId("Test task");
		task.setTitle("Test title");
		task.setDescription("Test description");
		task.setDuration(25);
		task.setDeliverable("Test deliverable");
		task.setPerson(name);
		
		Person person = new Person();
		person.setName(name);
		
		person.addTask(task);
		person.addTask(task);
		
		assertEquals(person.getHours(), 25);
		assertEquals(person.getTasks().size(), 1);
	}
	
	@Test
	public void testPersonAddTask6() {

		// add a task that has different person name assigned
	
		String name1 = "Mark Smith";
		String name2 = "saly kouler";
		
		Task task = new Task();
		Calendar testDeadline = Calendar.getInstance();
		task.setDeadline(testDeadline);
		task.setId("Test task");
		task.setTitle("Test title");
		task.setDescription("Test description");
		task.setDuration(25);
		task.setDeliverable("Test deliverable");
		task.setPerson(name1);
		
		Person person = new Person();
		person.setName(name2);
		
		person.addTask(task);
		
		assertEquals(person.getHours(), 25);
		assertEquals(person.getTasks().size(), 1);

		String taskN = person.getTasks().firstEntry().getValue().getPerson(); 
		assertTrue(taskN.equals(person.getName()));
	}
	
	@Test
	public void testPersonAddTask7() {

		// add two different tasks
	
		String name = "Mark Smith";
		Person person = new Person();
		person.setName(name);
		
		Task task1 = new Task();
		Task task2 = new Task();
		Task task3 = new Task();
		
		Calendar testDeadline = Calendar.getInstance();
		task1.setDeadline(testDeadline);
		task1.setId("Test task1");
		task1.setTitle("Test title");
		task1.setDescription("Test description");
		task1.setDuration(25);
		task1.setDeliverable("Test deliverable");
		task1.setPerson(name);
		
		task2.setDeadline(testDeadline);
		task2.setId("Test task2");
		task2.setTitle("Test title");
		task2.setDescription("Test description");
		task2.setDuration(25);
		task2.setDeliverable("Test deliverable");
		task2.setPerson(name);
	
		
		person.addTask(task1);
		person.addTask(task2);
		
		assertEquals(person.getHours(), 50);
		assertEquals(person.getTasks().size(), 2);
		
		task3.setDeadline(testDeadline);
		task3.setId("Test task3");
		task3.setTitle("Test title");
		task3.setDescription("Test description");
		task3.setDuration(25);
		task3.setDeliverable("Test deliverable");
		task3.setPerson(name);
		
		person.addTask(task3);
		
		assertEquals(person.getHours(), 75);
		assertEquals(person.getTasks().size(), 3);
		
	}
	
	@Test
	public void testPersonGetTasks1() {
		Person person = new Person();
		assertEquals(person.getTasks().size(), 0);
	}
	
	@Test
	public void testPersonGetTasks2() {
		
		String name = "saly kouler";
		
		Task task = new Task();
		Calendar testDeadline = Calendar.getInstance();
		task.setDeadline(testDeadline);
		task.setId("Test task");
		task.setTitle("Test title");
		task.setDescription("Test description");
		task.setDuration(25);
		task.setDeliverable("Test deliverable");
		task.setPerson(name);
		
		Person person = new Person();
		person.setName(name);
		person.addTask(task);
		
		assertEquals(person.getTasks().size(), 1);
		assertEquals(person.getHours(), 25);
		String taskN = person.getTasks().firstEntry().getValue().getPerson(); 
		assertTrue( taskN.equals(person.getName()));
	}
	
	@Test
	public void testPersonGetTasks3() {

		// add two different tasks
	
		String name = "Mark Smith";
		Person person = new Person();
		person.setName(name);
		
		Task task1 = new Task();
		Task task2 = new Task();
		Task task3 = new Task();
		
		Calendar testDeadline = Calendar.getInstance();
		task1.setDeadline(testDeadline);
		task1.setId("Test task1");
		task1.setTitle("Test title");
		task1.setDescription("Test description");
		task1.setDuration(25);
		task1.setDeliverable("Test deliverable");
		task1.setPerson(name);
		
		task2.setDeadline(testDeadline);
		task2.setId("Test task2");
		task2.setTitle("Test title");
		task2.setDescription("Test description");
		task2.setDuration(25);
		task2.setDeliverable("Test deliverable");
		task2.setPerson(name);
	
		
		person.addTask(task1);
		person.addTask(task2);
		
		assertEquals(person.getHours(), 50);
		assertEquals(person.getTasks().size(), 2);
		
		task3.setDeadline(testDeadline);
		task3.setId("Test task3");
		task3.setTitle("Test title");
		task3.setDescription("Test description");
		task3.setDuration(25);
		task3.setDeliverable("Test deliverable");
		task3.setPerson(name);
		
		person.addTask(task3);
		
		assertEquals(person.getHours(), 75);
		assertEquals(person.getTasks().size(), 3);
	}
	
	@Test
	public void testPersonGetTaskList1() {
		Person person = new Person();
		String tasks = "";
		assertTrue(person.getTaskList().equals(tasks));
	}
	
	@Test
	public void testPersonGetTaskList2() {
		
		String name = "saly kouler";
		
		Task task = new Task();
		Calendar testDeadline = Calendar.getInstance();
		task.setDeadline(testDeadline);
		task.setId("Test task");
		task.setTitle("Test title");
		task.setDescription("Test description");
		task.setDuration(25);
		task.setDeliverable("Test deliverable");
		task.setPerson(name);
		
		Person person = new Person();
		person.setName(name);
		person.addTask(task);
		
		String tasks = "Test task";
		assertTrue(person.getTaskList().equals(tasks));
	}
	
	@Test
	public void testPersonGetTaskList3() {

		// add two different tasks
	
		String name = "Mark Smith";
		Person person = new Person();
		person.setName(name);
		
		Task task1 = new Task();
		Task task2 = new Task();
		Task task3 = new Task();
		
		Calendar testDeadline = Calendar.getInstance();
		task1.setDeadline(testDeadline);
		task1.setId("Test task1");
		task1.setTitle("Test title");
		task1.setDescription("Test description");
		task1.setDuration(25);
		task1.setDeliverable("Test deliverable");
		task1.setPerson(name);
		
		task2.setDeadline(testDeadline);
		task2.setId("Test task2");
		task2.setTitle("Test title");
		task2.setDescription("Test description");
		task2.setDuration(25);
		task2.setDeliverable("Test deliverable");
		task2.setPerson(name);
	
		task3.setDeadline(testDeadline);
		task3.setId("Test task3");
		task3.setTitle("Test title");
		task3.setDescription("Test description");
		task3.setDuration(25);
		task3.setDeliverable("Test deliverable");
		task3.setPerson(name);
		
		person.addTask(task1);
		person.addTask(task2);
		person.addTask(task3);
		
		String tasks = "Test task1, Test task2, Test task3";
		assertTrue(person.getTaskList().equals(tasks));
	}
}